/**
 * 
 */
package edu.umd.clip.lm.model.decoding;

import java.util.*;

import edu.umd.clip.lm.model.decoding.TrellisSlice.SliceItem;

/**
 * @author Denis Filimonov <den@cs.umd.edu>
 *
 */
public class RecursiveSliceItemIterator implements Iterator<SliceItem> {
	private final SliceItem head;
	private final int offset;
	private RecursiveSliceItemIterator previous;
	private final Iterator<SliceItem> prevLinks;
	private boolean done;
	
	public RecursiveSliceItemIterator(SliceItem head, int offset) {
		this.head = head;
		this.offset = offset;
		if (offset == 0) {
			this.prevLinks = null;
		} else {
			this.prevLinks = head.slice.getPreviousItems(head).iterator();
		}
		this.done = false;
	}

	/* (non-Javadoc)
	 * @see java.util.Iterator#hasNext()
	 */
	@Override
	public boolean hasNext() {
		if (offset == 0) return !done;
		
		if (previous == null || !previous.hasNext()) {
			while (prevLinks.hasNext()) {
				previous = new RecursiveSliceItemIterator(prevLinks.next(), offset-1);
				if (previous.hasNext()) return true;
			}
			return false;
		}
		return true;
	}

	/* (non-Javadoc)
	 * @see java.util.Iterator#next()
	 */
	@Override
	public SliceItem next() {
		if (offset == 0) {
			done = true;
			return head;
		}
		if (hasNext()) {
			return previous.next();
		}
		throw new NoSuchElementException();
	}

	/* (non-Javadoc)
	 * @see java.util.Iterator#remove()
	 */
	@Override
	public void remove() {
		throw new UnsupportedOperationException();
	}

}
